<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

/**
 * 家庭关系模型
 * 管理员工的家庭成员信息和关系
 */
class FamilyRelation extends Model
{
    use HasFactory;

    /**
     * 表名
     */
    protected $table = 'family_relations';

    /**
     * 可填充字段
     */
    protected $fillable = [
        'employee_id',
        'name',
        'relationship_type',
        'relationship_name',
        'relationship_level',
        'gender',
        'birth_date',
        'age',
        'id_card',
        'phone',
        'occupation',
        'work_unit',
        'education_level',
        'school_name',
        'marital_status',
        'spouse_name',
        'marriage_date',
        'children_count',
        'children_info',
        'health_status',
        'health_notes',
        'is_deceased',
        'deceased_date',
        'residence_type',
        'residence_address',
        'residence_province',
        'residence_city',
        'economic_status',
        'monthly_income',
        'economic_notes',
        'has_social_security',
        'social_security_type',
        'social_security_number',
        'is_emergency_contact',
        'emergency_contact_priority',
        'notes',
        'special_circumstances',
        'is_verified',
        'verified_by',
        'verified_at',
        'is_active',
        'sort_order',
    ];

    /**
     * 字段类型转换
     */
    protected $casts = [
        'birth_date' => 'date',
        'marriage_date' => 'date',
        'deceased_date' => 'date',
        'verified_at' => 'date',
        'is_deceased' => 'boolean',
        'is_verified' => 'boolean',
        'is_active' => 'boolean',
        'is_emergency_contact' => 'boolean',
        'has_social_security' => 'boolean',
        'children_count' => 'integer',
        'monthly_income' => 'decimal:2',
        'children_info' => 'array',
    ];

    /**
     * 日期字段
     */
    protected $dates = [
        'birth_date',
        'marriage_date',
        'deceased_date',
        'verified_at',
        'created_at',
        'updated_at',
    ];

    // ============ 常量定义 ============

    public const RELATIONSHIP_FATHER = 'father';
    public const RELATIONSHIP_MOTHER = 'mother';
    public const RELATIONSHIP_SPOUSE = 'spouse';
    public const RELATIONSHIP_CHILD = 'child';
    public const RELATIONSHIP_SIBLING = 'sibling';
    public const RELATIONSHIP_GRANDPARENT = 'grandparent';
    public const RELATIONSHIP_GRANDCHILD = 'grandchild';
    public const RELATIONSHIP_AUNT_UNCLE = 'aunt_uncle';
    public const RELATIONSHIP_NIECE_NEPHEW = 'niece_nephew';
    public const RELATIONSHIP_COUSIN = 'cousin';
    public const RELATIONSHIP_IN_LAW = 'in_law';

    public const GENDER_MALE = 'male';
    public const GENDER_FEMALE = 'female';

    public const MARITAL_SINGLE = 'single';
    public const MARITAL_MARRIED = 'married';
    public const MARITAL_DIVORCED = 'divorced';
    public const MARITAL_WIDOWED = 'widowed';

    public const RESIDENCE_TOGETHER = 'together';
    public const RESIDENCE_SEPARATE = 'separate';
    public const RESIDENCE_ABROAD = 'abroad';

    public const ECONOMIC_EXCELLENT = 'excellent';
    public const ECONOMIC_GOOD = 'good';
    public const ECONOMIC_AVERAGE = 'average';
    public const ECONOMIC_POOR = 'poor';

    // ============ 关联关系 ============

    /**
     * 关联员工
     */
    public function employee(): BelongsTo
    {
        return $this->belongsTo(Employee::class);
    }

    // ============ 访问器 ============

    /**
     * 获取关系类型标签
     */
    public function getRelationshipTypeLabelAttribute(): string
    {
        return match($this->relationship_type) {
            self::RELATIONSHIP_FATHER => '父亲',
            self::RELATIONSHIP_MOTHER => '母亲',
            self::RELATIONSHIP_SPOUSE => '配偶',
            self::RELATIONSHIP_CHILD => '子女',
            self::RELATIONSHIP_SIBLING => '兄弟姐妹',
            self::RELATIONSHIP_GRANDPARENT => '祖父母',
            self::RELATIONSHIP_GRANDCHILD => '孙子女',
            self::RELATIONSHIP_AUNT_UNCLE => '叔伯姑姨',
            self::RELATIONSHIP_NIECE_NEPHEW => '侄子侄女',
            self::RELATIONSHIP_COUSIN => '堂兄弟姐妹',
            self::RELATIONSHIP_IN_LAW => '姻亲',
            default => $this->relationship_name ?? $this->relationship_type ?? '未知'
        };
    }

    /**
     * 获取性别标签
     */
    public function getGenderLabelAttribute(): string
    {
        return match($this->gender) {
            self::GENDER_MALE => '男',
            self::GENDER_FEMALE => '女',
            default => '未知'
        };
    }

    /**
     * 获取婚姻状况标签
     */
    public function getMaritalStatusLabelAttribute(): string
    {
        return match($this->marital_status) {
            self::MARITAL_SINGLE => '未婚',
            self::MARITAL_MARRIED => '已婚',
            self::MARITAL_DIVORCED => '离异',
            self::MARITAL_WIDOWED => '丧偶',
            default => '未知'
        };
    }

    /**
     * 获取居住类型标签
     */
    public function getResidenceTypeLabelAttribute(): string
    {
        return match($this->residence_type) {
            self::RESIDENCE_TOGETHER => '同住',
            self::RESIDENCE_SEPARATE => '分居',
            self::RESIDENCE_ABROAD => '海外',
            default => '未知'
        };
    }

    /**
     * 获取经济状况标签
     */
    public function getEconomicStatusLabelAttribute(): string
    {
        return match($this->economic_status) {
            self::ECONOMIC_EXCELLENT => '优越',
            self::ECONOMIC_GOOD => '良好',
            self::ECONOMIC_AVERAGE => '一般',
            self::ECONOMIC_POOR => '困难',
            default => '未知'
        };
    }

    /**
     * 获取年龄（自动计算）
     */
    public function getAgeAttribute($value): ?int
    {
        if ($value) {
            return $value;
        }

        if ($this->birth_date) {
            return $this->birth_date->age;
        }

        return null;
    }

    /**
     * 获取是否成年
     */
    public function getIsAdultAttribute(): bool
    {
        return $this->age >= 18;
    }

    /**
     * 获取是否需要赡养
     */
    public function getNeedsSupportAttribute(): bool
    {
        if ($this->is_deceased) {
            return false;
        }

        // 65岁以上或未成年需要赡养
        return ($this->age >= 65) || ($this->age <= 18 && $this->age > 0);
    }

    /**
     * 获取关系层级标签
     */
    public function getRelationshipLevelLabelAttribute(): string
    {
        return match($this->relationship_level) {
            1 => '直系',
            2 => '二级',
            3 => '三级',
            default => '其他'
        };
    }

    /**
     * 获取居住地信息
     */
    public function getResidenceInfoAttribute(): string
    {
        if (!$this->residence_province && !$this->residence_city) {
            return '未知';
        }

        $info = '';
        if ($this->residence_province) {
            $info .= $this->residence_province;
        }
        if ($this->residence_city) {
            $info .= ' ' . $this->residence_city;
        }

        return $info;
    }

    /**
     * 获取社保信息
     */
    public function getSocialSecurityInfoAttribute(): string
    {
        if (!$this->has_social_security) {
            return '无社保';
        }

        $info = $this->social_security_type ?? '社保';
        if ($this->social_security_number) {
            $info .= " ({$this->social_security_number})";
        }

        return $info;
    }

    // ============ 作用域 ============

    /**
     * 直系亲属作用域
     */
    public function scopeImmediateFamily($query)
    {
        return $query->whereIn('relationship_type', [
            self::RELATIONSHIP_FATHER,
            self::RELATIONSHIP_MOTHER,
            self::RELATIONSHIP_SPOUSE,
            self::RELATIONSHIP_CHILD,
        ]);
    }

    /**
     * 紧急联系人作用域
     */
    public function scopeEmergencyContacts($query)
    {
        return $query->where('is_emergency_contact', true)
                    ->orderBy('emergency_contact_priority');
    }

    /**
     * 已故亲属作用域
     */
    public function scopeDeceased($query)
    {
        return $query->where('is_deceased', true);
    }

    /**
     * 需要赡养作用域
     */
    public function scopeNeedsSupport($query)
    {
        return $query->where('is_deceased', false)
                    ->where(function ($query) {
                        $query->where('age', '>=', 65)
                              ->orWhere('age', '<=', 18);
                    });
    }

    /**
     * 按关系类型筛选作用域
     */
    public function scopeByRelationshipType($query, $type)
    {
        return $query->where('relationship_type', $type);
    }

    /**
     * 按关系层级筛选作用域
     */
    public function scopeByRelationshipLevel($query, $level)
    {
        return $query->where('relationship_level', $level);
    }

    /**
     * 按年龄范围筛选作用域
     */
    public function scopeByAgeRange($query, $minAge, $maxAge)
    {
        return $query->whereBetween('age', [$minAge, $maxAge]);
    }

    /**
     * 已验证作用域
     */
    public function scopeVerified($query)
    {
        return $query->where('is_verified', true);
    }

    /**
     * 有社保作用域
     */
    public function scopeHasSocialSecurity($query)
    {
        return $query->where('has_social_security', true);
    }

    // ============ 业务方法 ============

    /**
     * 验证家庭关系
     */
    public function verify(string $verifiedBy): bool
    {
        $this->is_verified = true;
        $this->verified_by = $verifiedBy;
        $this->verified_at = now();

        return $this->save();
    }

    /**
     * 取消验证
     */
    public function unverify(): bool
    {
        $this->is_verified = false;
        $this->verified_by = null;
        $this->verified_at = null;

        return $this->save();
    }

    /**
     * 设置为紧急联系人
     */
    public function setAsEmergencyContact(int $priority = 1): bool
    {
        $this->is_emergency_contact = true;
        $this->emergency_contact_priority = $priority;

        return $this->save();
    }

    /**
     * 取消紧急联系人
     */
    public function removeEmergencyContact(): bool
    {
        $this->is_emergency_contact = false;
        $this->emergency_contact_priority = null;

        return $this->save();
    }

    /**
     * 标记为已故
     */
    public function markAsDeceased(\DateTime $deceasedDate): bool
    {
        $this->is_deceased = true;
        $this->deceased_date = $deceasedDate;

        return $this->save();
    }

    /**
     * 更新子女信息
     */
    public function updateChildrenInfo(array $childrenInfo): bool
    {
        $this->children_info = $childrenInfo;
        $this->children_count = count($childrenInfo);

        return $this->save();
    }

    /**
     * 添加子女
     */
    public function addChild(array $childInfo): bool
    {
        $children = $this->children_info ?? [];
        $children[] = $childInfo;

        return $this->updateChildrenInfo($children);
    }

    /**
     * 更新联系信息
     */
    public function updateContactInfo(array $contactInfo): bool
    {
        $fillableFields = [
            'phone', 'occupation', 'work_unit', 'residence_type',
            'residence_address', 'residence_province', 'residence_city',
            'economic_status', 'monthly_income', 'economic_notes',
            'has_social_security', 'social_security_type', 'social_security_number'
        ];

        $updateData = array_intersect_key($contactInfo, array_flip($fillableFields));

        return $this->update($updateData);
    }

    // ============ 静态方法 ============

    /**
     * 获取关系类型选项
     */
    public static function getRelationshipTypeOptions(): array
    {
        return [
            self::RELATIONSHIP_FATHER => '父亲',
            self::RELATIONSHIP_MOTHER => '母亲',
            self::RELATIONSHIP_SPOUSE => '配偶',
            self::RELATIONSHIP_CHILD => '子女',
            self::RELATIONSHIP_SIBLING => '兄弟姐妹',
            self::RELATIONSHIP_GRANDPARENT => '祖父母',
            self::RELATIONSHIP_GRANDCHILD => '孙子女',
            self::RELATIONSHIP_AUNT_UNCLE => '叔伯姑姨',
            self::RELATIONSHIP_NIECE_NEPHEW => '侄子侄女',
            self::RELATIONSHIP_COUSIN => '堂兄弟姐妹',
            self::RELATIONSHIP_IN_LAW => '姻亲',
        ];
    }

    /**
     * 获取关系层级选项
     */
    public static function getRelationshipLevelOptions(): array
    {
        return [
            1 => '直系亲属',
            2 => '二级亲属',
            3 => '三级亲属',
            4 => '远亲',
        ];
    }

    /**
     * 获取反向关系
     */
    public static function getReverseRelationship(string $relationshipType, string $gender): string
    {
        $reverseMap = [
            self::RELATIONSHIP_FATHER => [
                self::GENDER_MALE => self::RELATIONSHIP_CHILD,
                self::GENDER_FEMALE => self::RELATIONSHIP_CHILD,
            ],
            self::RELATIONSHIP_MOTHER => [
                self::GENDER_MALE => self::RELATIONSHIP_CHILD,
                self::GENDER_FEMALE => self::RELATIONSHIP_CHILD,
            ],
            self::RELATIONSHIP_SPOUSE => [
                self::GENDER_MALE => self::RELATIONSHIP_SPOUSE,
                self::GENDER_FEMALE => self::RELATIONSHIP_SPOUSE,
            ],
            self::RELATIONSHIP_CHILD => [
                self::GENDER_MALE => self::RELATIONSHIP_FATHER,
                self::GENDER_FEMALE => self::RELATIONSHIP_MOTHER,
            ],
            self::RELATIONSHIP_SIBLING => [
                self::GENDER_MALE => self::RELATIONSHIP_SIBLING,
                self::GENDER_FEMALE => self::RELATIONSHIP_SIBLING,
            ],
        ];

        return $reverseMap[$relationshipType][$gender] ?? $relationshipType;
    }

    /**
     * 验证家庭关系数据
     */
    public static function validateFamilyData(array $data): array
    {
        $errors = [];

        // 必填字段验证
        $requiredFields = ['employee_id', 'name', 'relationship_type'];
        foreach ($requiredFields as $field) {
            if (empty($data[$field])) {
                $errors[] = "{$field} 字段不能为空";
            }
        }

        // 关系类型验证
        $validRelationshipTypes = array_keys(self::getRelationshipTypeOptions());
        if (!empty($data['relationship_type']) && !in_array($data['relationship_type'], $validRelationshipTypes)) {
            $errors[] = "无效的关系类型";
        }

        // 年龄验证
        if (!empty($data['age']) && (!is_numeric($data['age']) || $data['age'] < 0 || $data['age'] > 150)) {
            $errors[] = "年龄必须在0-150岁之间";
        }

        // 子女数量验证
        if (!empty($data['children_count']) && (!is_numeric($data['children_count']) || $data['children_count'] < 0)) {
            $errors[] = "子女数量必须是有效的非负数";
        }

        // 月收入验证
        if (!empty($data['monthly_income']) && (!is_numeric($data['monthly_income']) || $data['monthly_income'] < 0)) {
            $errors[] = "月收入必须是有效的非负数";
        }

        // 紧急联系人优先级验证
        if (!empty($data['emergency_contact_priority']) && (!is_numeric($data['emergency_contact_priority']) || $data['emergency_contact_priority'] < 1 || $data['emergency_contact_priority'] > 3)) {
            $errors[] = "紧急联系人优先级必须在1-3之间";
        }

        // 时间验证
        if (!empty($data['birth_date']) && !empty($data['marriage_date'])) {
            $birthDate = strtotime($data['birth_date']);
            $marriageDate = strtotime($data['marriage_date']);

            if ($birthDate && $marriageDate && $birthDate >= $marriageDate) {
                $errors[] = "结婚日期必须晚于出生日期";
            }
        }

        return $errors;
    }

    /**
     * 创建反向关系记录
     */
    public static function createReverseRelation(int $employeeId, array $data): ?self
    {
        // 对于某些关系，需要创建反向关系记录
        $reverseRelationships = [
            self::RELATIONSHIP_SPOUSE => self::RELATIONSHIP_SPOUSE,
            self::RELATIONSHIP_CHILD => [self::RELATIONSHIP_FATHER, self::RELATIONSHIP_MOTHER],
            self::RELATIONSHIP_SIBLING => self::RELATIONSHIP_SIBLING,
        ];

        if (!isset($reverseRelationships[$data['relationship_type']])) {
            return null;
        }

        $reverseType = $reverseRelationships[$data['relationship_type']];
        if (is_array($reverseType)) {
            // 根据性别选择反向关系
            $gender = $data['gender'] ?? self::GENDER_MALE;
            $reverseType = $reverseType[$gender] ?? $reverseType[self::GENDER_MALE];
        }

        $reverseData = array_merge($data, [
            'employee_id' => $employeeId,
            'relationship_type' => $reverseType,
            'relationship_name' => self::getRelationshipTypeOptions()[$reverseType] ?? $reverseType,
            'relationship_level' => $data['relationship_level'] ?? 1,
        ]);

        return self::create($reverseData);
    }
}
